#ifndef PGL_DATA_REGISTRY_H
#define PGL_DATA_REGISTRY_H

#pragma once


namespace pgl
{

class CDataRegistrySingleton;

/*! \brief Data Object Registry class to store Runtime class information

	This class is a Destruction-Manager singleton

  \ingroup PGLGroup
*/
class CDataRegistry
{
public:
	typedef std::map<std::_tstring, CPGLDataPtr (__cdecl *)(void)> CRegistry;

	//! \name Constructors
	//@{

	//! Initialize the Singleton object 
	CDataRegistry();
	//! destroy the Singleton object 
	~CDataRegistry();
	//@}


protected:
	friend class CDataRegistrySingleton;
	//! \name Register methods
	//@{
	//! return type count
	size_t GetCountP() const					{	return m_registry.size();};
	//! add data type
	void RegisterDataP(LPCTSTR szName, CPGLDataPtr (__cdecl *fcn)(void) );
	//! return empty data object
	CPGLDataPtr GetDataP(LPCTSTR szName);
	//@}
	CRegistry m_registry;
};


/*! \brief Data factory map

  \ingroup PGLCoreSingletonGroup
*/
class PGLCORE_EXT_CLASS CDataRegistrySingleton : public singletons::TSingleton<CDataRegistry, 2>
{
public:
	//! return type count
	static size_t GetCount();
	//! add data type
	static void RegisterData(LPCTSTR szName, CPGLDataPtr (__cdecl *fcn)(void) );
	//! return empty data object
	static CPGLDataPtr GetData(LPCTSTR szName);
};

/*! \brief A dummy class to use CDataRegistry.

	This class is used internally.
\ingroup PGLCoreSingletonGroup
*/
class CDataRegisterer
{
public:
	CDataRegisterer(LPCTSTR szName=_T("CUnknown"), CPGLDataPtr (*fcn)(void) = NULL );
};

};

/* \def PGL_REGISTER_DATA_TYPE

  Macro to be inserted in the implementation of inherited classes from CPGLData.
  Registers data objet into registry.
\ingroup PGLDataGroup
*/
#ifndef PGL_REGISTER_DATA_TYPE
#define PGL_REGISTER_DATA_TYPE( className )\
	namespace pgl \
	{ \
	static CDataRegisterer dataObject##className( _T( #className ), className::GetEmpty ##className );\
	}
#endif

#endif